﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Kiiro.Common.Entities;
using Kiiro.Common.Interfaces;
using Kiiro.Common.Utility;
using Kiiro.ExceptionManagement;
using Kiiro.Model.Utility;
using Permissions = Kiiro.Common.Utility.Constants.Permissions;
using AppName = Kiiro.Common.Utility.Constants.AppName;
using SecurityConstants = Kiiro.Common.Utility.Constants.Security;


namespace Kiiro.Model
{
    /// <summary>
    /// Kiiro SharePoint Permissions Wrapper
    /// </summary>
    /// <see cref="http://nform-pdc/midori/v2/Project%20Documents/Midori%20V2%20Permissions.xlsx"/>
    /// <seealso cref="http://nform-pdc/midori/v2/Project%20Documents/Midori%20V2%20Requirements.docx"/>
    public class PermissionsModel
    {
        public static bool LicenseKeyIsValid
        {
            get;
            set;
        }

        /// <summary>
        /// Check whether the Kiiro portal site described by siteCollectionId and serverRelativeUrl has unique permissions
        /// </summary>
        internal static bool PortalWebHasUniquePermissions ( Guid siteCollectionId, string serverRelativeUrl )
        {
            bool hasUniquePermissions = false;
            using ( SPWeb web = SPHelpers.GetSystemWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                using ( SPWeb portalWeb = SPHelpers.IsProject ( web ) ? web.ParentWeb : web )
                {
                    hasUniquePermissions = web.HasUniqueRoleAssignments;
                }
            }
            return hasUniquePermissions;
        }

        internal static void RemoveCustomGroupsFromSharePoint ( Guid siteCollectionId, string serverRelativeUrl, string webTitle )
        {
            try
            {
                using ( SPWeb systemWeb = SPHelpers.GetSystemWeb ( siteCollectionId, serverRelativeUrl ) )
                {
                    if ( systemWeb.HasUniqueRoleAssignments )
                    {
                        systemWeb.AllowUnsafeUpdates = true;
                        if ( systemWeb.AssociatedOwnerGroup != null )
                            systemWeb.SiteGroups.Remove ( systemWeb.AssociatedOwnerGroup.Name );
                        if ( systemWeb.AssociatedMemberGroup != null )
                            systemWeb.SiteGroups.Remove ( systemWeb.AssociatedMemberGroup.Name );
                        if ( systemWeb.AssociatedVisitorGroup != null )
                            systemWeb.SiteGroups.Remove ( systemWeb.AssociatedVisitorGroup.Name );
                        systemWeb.Update ( );
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }
        }

        internal static bool SetPortalGroups ( Guid siteCollectionId, string serverRelativeUrl, User user )
        {
            bool groupsSet = false;

            if ( user != null )
            {
                using ( SPWeb systemWeb = SPHelpers.GetSystemWeb ( siteCollectionId, serverRelativeUrl ) )
                {
                    systemWeb.AllowUnsafeUpdates = true;

                    SPUser spUser = default ( SPUser );
                    string login = default ( string );

                    if ( !string.IsNullOrEmpty ( user.Login ) )
                    {
                        login = user.IsFormsUser ? string.Format ( "kiiromembership:{0}", user.Login ) : user.Login;

                        systemWeb.SiteUsers.Add ( login, user.Email, user.FullName, "" );
                        spUser = systemWeb.EnsureUser ( login );
                    }
                    else if ( user.SPUserId != default ( int ) )
                    {
                        spUser = systemWeb.AllUsers.GetByID ( user.SPUserId );
                        login = spUser.LoginName;
                    }

                    if ( spUser != default ( SPUser ) && login != default ( string ) )
                    {
                        if ( user.EditType == EditType.Created || user.EditType == EditType.Updated )
                        {
                            systemWeb.AssociatedMemberGroup.AddUser ( login, user.Email, user.FullName, "" );

                            if ( user.IsAdministrator || user.ManageProjectsOnly )
                                systemWeb.AssociatedOwnerGroup.AddUser ( login, user.Email, user.FullName, "" );
                            else if ( !user.IsAdministrator && !user.ManageProjectsOnly )
                                systemWeb.AssociatedOwnerGroup.RemoveUser ( spUser );
                        }
                        else if ( user.EditType == EditType.Deleted )
                        {
                            systemWeb.AssociatedOwnerGroup.RemoveUser ( spUser );
                            systemWeb.AssociatedMemberGroup.RemoveUser ( spUser );

                            for ( int i = spUser.Groups.Count - 1; i >= 0; i-- )
                            {
                                SPGroup group = spUser.Groups [ i ];
                                if ( SPHelpers.IsKiiro ( group.ParentWeb ) )
                                    group.RemoveUser ( spUser );
                            }
                        }

                        user.SPUserId = spUser.ID;
                        groupsSet = true;
                    }
                }
            }

            return groupsSet;
        }

        internal static bool SetProjectGroups ( Guid siteCollectionId, string serverRelativeUrl, TeamMember teamMember )
        {
            bool groupsSet = false;

            try
            {
                if ( teamMember != null && teamMember.User != null )
                {
                    List<bool> bits = teamMember.PermissionBitsTeams;
                    if ( bits != null && bits.Count > 0 && ( bits [ 0 ] || bits [ 2 ] || bits [ 3 ] ) )
                    {
                        using ( SPWeb systemWeb = SPHelpers.GetSystemWeb ( siteCollectionId, serverRelativeUrl ) )
                        {
                            User user = teamMember.User;
                            systemWeb.AllowUnsafeUpdates = true;
                            string login = user.IsFormsUser ? string.Format ( "kiiromembership:{0}", user.Login ) : user.Login;

                            systemWeb.SiteUsers.Add ( login, user.Email, user.FullName, "" );
                            SPUser spUser = systemWeb.EnsureUser ( login );

                            if ( teamMember.EditType == EditType.Created || teamMember.EditType == EditType.Updated )
                            {
                                systemWeb.AssociatedMemberGroup.AddUser ( login, user.Email, user.FullName, "" );

                                if ( teamMember.IsProjectManager )
                                    systemWeb.AssociatedOwnerGroup.AddUser ( login, user.Email, user.FullName, "" );
                                else
                                    systemWeb.AssociatedOwnerGroup.RemoveUser ( spUser );
                            }
                            else
                            {
                                systemWeb.AssociatedOwnerGroup.RemoveUser ( spUser );
                                systemWeb.AssociatedMemberGroup.RemoveUser ( spUser );
                            }

                            systemWeb.AllowUnsafeUpdates = false;
                            groupsSet = true;
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }

            return groupsSet;
        }

        public static void GetGlobalPermissionBitsForCurrentUser ( IPermissions permissionsObject, User currentUser, Guid siteCollectionId, string serverRelativeUrl )
        {
            GetGlobalPermissionBitsForCurrentUser ( permissionsObject, currentUser, siteCollectionId, serverRelativeUrl, false );
        }

        public static void GetGlobalPermissionBitsForCurrentUser ( IPermissions iPermissions, User user, Guid siteCollectionId, string serverRelativeUrl, bool requiresPortal )
        {
            SPWeb web = null;

            try
            {
                LicenseKeyIsValid = LicensingModel.ValidateLicenseKeys ( iPermissions, siteCollectionId, serverRelativeUrl );

                string login = user.IsFormsUser ? string.Format ( "kiiromembership:{0}", user.Login ) : user.Login;
                if ( requiresPortal )
                    web = SPHelpers.GetPortalWeb ( siteCollectionId, serverRelativeUrl, login );
                else
                    web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl, login );

                iPermissions.PermissionBitsSetup = GetSPGroupCRUDPermissionBits (
                    iPermissions, user, web, EntityType.Setup, siteCollectionId, serverRelativeUrl );
                iPermissions.PermissionBitsUsers = GetSPGroupCRUDPermissionBits (
                    iPermissions, user, web, EntityType.User, siteCollectionId, serverRelativeUrl );
                iPermissions.PermissionBitsProjects = GetSPGroupCRUDPermissionBits (
                    iPermissions, user, web, EntityType.Project, siteCollectionId, serverRelativeUrl );

                if ( LicenseKeyIsValid && user.Login.ToLower ( ) != SecurityConstants.AD_AUTH_USERS_DOMAIN_GROUP_NAME.ToLower ( ) )
                {
                    iPermissions.PermissionBitsActivity = GetSPGroupCRUDPermissionBits (
                        iPermissions, user, web, EntityType.Activity, siteCollectionId, serverRelativeUrl );
                    iPermissions.PermissionBitsTeams = GetSPGroupCRUDPermissionBits (
                        iPermissions, user, web, EntityType.Teams, siteCollectionId, serverRelativeUrl );
                    iPermissions.PermissionBitsWork = GetSPGroupCRUDPermissionBits (
                        iPermissions, user, web, EntityType.Work, siteCollectionId, serverRelativeUrl );
                    iPermissions.PermissionBitsDiscussions = GetSPGroupCRUDPermissionBits (
                        iPermissions, user, web, EntityType.Discussions, siteCollectionId, serverRelativeUrl );
                    iPermissions.PermissionBitsDocuments = GetSPGroupCRUDPermissionBits (
                        iPermissions, user, web, EntityType.Documents, siteCollectionId, serverRelativeUrl );
                    iPermissions.PermissionBitsLists = GetSPGroupCRUDPermissionBits (
                        iPermissions, user, web, EntityType.Lists, siteCollectionId, serverRelativeUrl );

                    iPermissions.PermissionBitsProjectPlanFile = GetSPGroupCRUDPermissionBitsForPlanFile (
                        iPermissions, user, web );
                }
                else
                {
                    iPermissions.PermissionBitsActivity = GetSPGroupCRUDPermissionBitsREADONLY (
                        iPermissions, user, web, EntityType.Activity );
                    iPermissions.PermissionBitsTeams = GetSPGroupCRUDPermissionBitsREADONLY (
                        iPermissions, user, web, EntityType.Teams );
                    iPermissions.PermissionBitsWork = GetSPGroupCRUDPermissionBitsREADONLY (
                        iPermissions, user, web, EntityType.Work );
                    iPermissions.PermissionBitsDiscussions = GetSPGroupCRUDPermissionBitsREADONLY (
                        iPermissions, user, web, EntityType.Discussions );
                    iPermissions.PermissionBitsDocuments = GetSPGroupCRUDPermissionBitsREADONLY (
                        iPermissions, user, web, EntityType.Documents );
                    iPermissions.PermissionBitsLists = GetSPGroupCRUDPermissionBitsREADONLY (
                        iPermissions, user, web, EntityType.Lists );

                    iPermissions.PermissionBitsProjectPlanFile = Permissions.PermissionBitsREADONLY;
                }
            }
            finally
            {
                iPermissions.LicenseKeyIsValid = LicenseKeyIsValid;
                if ( web != null )
                    web.Dispose ( );
            }
        }

        private static List<bool> GetSPGroupCRUDPermissionBits ( IPermissions iPermissions, User user, SPWeb web, EntityType entityType, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canCreate = false;
            bool canRead = false;
            bool canUpdate = false;
            bool canDelete = false;

            bool readOnly = false;

            if ( SPHelpers.IsProject ( siteCollectionId, serverRelativeUrl ) )
            {
                // READONLY if accessing from inside a project site and the project is closed
                Project project = ProjectsModel.GetByServerRelativeWebUrl ( siteCollectionId, serverRelativeUrl );
                if ( project != null && project.ProjectStatus == ProjectStatus.Closed || iPermissions.LicenseKeyBits.Contains ( true ) )
                {
                    readOnly = true;
                }
            }

            if ( readOnly )
            {
                if ( entityType == EntityType.Project )
                {
                    canUpdate = CanUserUpdateItem ( iPermissions, user, entityType, web );
                    canDelete = CanUserDeleteItem ( iPermissions, user, entityType, web );
                }
                else if ( entityType == EntityType.User )
                {
                    canUpdate = CanUserUpdateItem ( iPermissions, user, entityType, web );
                    iPermissions.CanUserUpdateThemselves = canUpdate;
                }
                else if ( entityType == EntityType.Setup )
                {
                    canCreate = CanUserCreateItem ( iPermissions, user, entityType, web );
                    canUpdate = CanUserUpdateItem ( iPermissions, user, entityType, web );
                }
            }
            else
            {
                canCreate = CanUserCreateItem ( iPermissions, user, entityType, web );
                if ( canCreate && ( entityType == EntityType.Project || entityType == EntityType.User ) )
                {
                    if ( entityType == EntityType.Project )
                        canCreate = LicensingModel.CanIncrementOpenProjectCount ( siteCollectionId, serverRelativeUrl );
                    else if ( entityType == EntityType.User )
                        canCreate = LicensingModel.CanIncrementActiveUsersCount ( siteCollectionId, serverRelativeUrl );
                }

                canRead = CanUserReadItem ( iPermissions, user, entityType, web );

                canUpdate = CanUserUpdateItem ( iPermissions, user, entityType, web );
                if ( entityType == EntityType.User )
                    iPermissions.CanUserUpdateThemselves = canUpdate;
                else if ( entityType == EntityType.Work )
                    iPermissions.CanTeamMemberUpdateWork = canUpdate;
                else if ( entityType == EntityType.Discussions )
                    iPermissions.CanTeamMemberUpdateDiscussion = canUpdate;

                canDelete = CanUserDeleteItem ( iPermissions, user, entityType, web );
                if ( entityType == EntityType.Discussions )
                    iPermissions.CanTeamMemberUpdateDiscussion = canDelete;
            }

            return new List<bool> { canCreate, canRead, canUpdate, canDelete };
        }

        private static List<bool> GetSPGroupCRUDPermissionBitsForPlanFile ( IPermissions permissionsObject, User currentUser, SPWeb web )
        {
            bool canUpdate = currentUser.Groups.Contains ( KiiroGroup.PortalOwner ) || currentUser.Groups.Contains ( KiiroGroup.ProjectOwner );
            return new List<bool> { false, true, canUpdate, false };
        }

        private static List<bool> GetSPGroupCRUDPermissionBitsREADONLY ( IPermissions permissionsObject, User currentUser, SPWeb web, EntityType entityType )
        {
            bool canRead = CanUserReadItem ( permissionsObject, currentUser, entityType, web );
            return new List<bool> { false, canRead, false, false };
        }

        internal static bool CanUserCreateItem ( IPermissions permissionsObject, User currentUser, EntityType entityType, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canCreate = false;
            using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                canCreate = CanUserCreateItem ( permissionsObject, currentUser, entityType, web );
            }
            return canCreate;
        }

        private static bool CanUserCreateItem ( IPermissions permissionsObject, User currentUser, EntityType entityType, SPWeb web )
        {
            bool canCreate = false;

            Guid siteCollectionId = default ( Guid );
            string serverRelativeUrl = default ( string );
            SPHelpers.GetSiteCollectionIdAndServerRelativeUrl ( web.Url, out siteCollectionId, out serverRelativeUrl );

            if ( currentUser.Groups.Contains ( KiiroGroup.PortalOwner ) )
            {
                if ( entityType == EntityType.Activity )
                    canCreate = false;
                else if ( entityType == EntityType.User )
                    canCreate = !currentUser.ManageProjectsOnly && LicensingModel.CanIncrementActiveUsersCount ( siteCollectionId, serverRelativeUrl );
                else if ( entityType == EntityType.Setup )
                    canCreate = !currentUser.ManageProjectsOnly;
                else if ( entityType == EntityType.Project )
                    canCreate = LicensingModel.CanIncrementOpenProjectCount ( siteCollectionId, serverRelativeUrl );
                else
                    canCreate = LicenseKeyIsValid;
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.ProjectOwner ) )
            {
                switch ( entityType )
                {
                    case EntityType.Setup:
                    case EntityType.User:
                    case EntityType.Project:
                        canCreate = false;
                        break;
                    case EntityType.Activity:
                    case EntityType.Teams:
                    case EntityType.Work:
                    case EntityType.Discussions:
                    case EntityType.Documents:
                    case EntityType.Lists:
                        canCreate = LicenseKeyIsValid;
                        break;
                }
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.ProjectMember ) )
            {
                switch ( entityType )
                {
                    case EntityType.Setup:
                    case EntityType.User:
                    case EntityType.Project:
                    case EntityType.Teams:
                        canCreate = false;
                        break;
                    case EntityType.Activity:
                    case EntityType.Work:
                    case EntityType.Discussions:
                    case EntityType.Documents:
                    case EntityType.Lists:
                        canCreate = LicenseKeyIsValid;
                        break;
                }
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.PortalMember ) )
            {
                if ( entityType == EntityType.Activity )
                    canCreate = LicenseKeyIsValid;
                else
                    canCreate = false;
            }
            else
                canCreate = false;

            return canCreate;
        }

        internal static bool CanUserReadItem ( IPermissions permissionsObject, User currentUser, EntityType entityType, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canRead = false;
            using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                canRead = CanUserReadItem ( permissionsObject, currentUser, entityType, web );
            }
            return canRead;
        }

        private static bool CanUserReadItem ( IPermissions permissionsObject, User currentUser, EntityType entityType, SPWeb web )
        {
            bool canRead = false;

            if ( currentUser.Groups.Contains ( KiiroGroup.PortalOwner ) ||
                currentUser.Groups.Contains ( KiiroGroup.ProjectOwner ) ||
                currentUser.Groups.Contains ( KiiroGroup.ProjectMember ) )
            {
                canRead = LicenseKeyIsValid;
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.PortalMember ) )
            {
                switch ( entityType )
                {
                    case EntityType.Setup:
                    case EntityType.User:
                    case EntityType.Project:
                    case EntityType.Activity:
                        canRead = LicenseKeyIsValid;
                        break;
                    case EntityType.Teams:
                    case EntityType.Work:
                    case EntityType.Discussions:
                    case EntityType.Documents:
                    case EntityType.Lists:
                        canRead = false;
                        break;
                }
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.Visitor ) )
            {
                switch ( entityType )
                {
                    case EntityType.Setup:
                    case EntityType.User:
                        canRead = LicenseKeyIsValid;
                        break;

                    case EntityType.Project:
                    case EntityType.Activity:
                    case EntityType.Teams:
                    case EntityType.Work:
                    case EntityType.Discussions:
                    case EntityType.Documents:
                    case EntityType.Lists:
                        canRead = false;
                        break;
                }
            }
            else
                canRead = false;

            return canRead;
        }

        internal static bool CanUserUpdateItem ( IPermissions permissionsObject, User currentUser, EntityType entityType, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canUpdate = false;
            using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                canUpdate = CanUserUpdateItem ( permissionsObject, currentUser, entityType, web );
            }
            return canUpdate;
        }

        private static bool CanUserUpdateItem ( IPermissions permissionsObject, User currentUser, EntityType entityType, SPWeb web )
        {
            bool canUpdate = false;

            if ( currentUser.Groups.Contains ( KiiroGroup.PortalOwner ) )
            {
                if ( entityType == EntityType.Activity )
                    canUpdate = false;
                else if ( entityType == EntityType.Setup )
                    canUpdate = !currentUser.ManageProjectsOnly;
                else if ( entityType == EntityType.User )
                    canUpdate = !currentUser.ManageProjectsOnly || CanUserUpdateThemselves ( currentUser.Id, currentUser.Login, permissionsObject.UserId );
                else
                    canUpdate = true;
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.ProjectOwner ) )
            {
                switch ( entityType )
                {
                    case EntityType.Setup:
                    case EntityType.Activity:
                        canUpdate = false;
                        break;
                    case EntityType.User:                   // needs to be true if we want to update the User.ProjectIds field of teamMembers
                    case EntityType.Project:                // PMs can update Project settings, however this needs to be true if we want to update the ProjectManagerIds field
                    case EntityType.Teams:
                    case EntityType.Work:
                    case EntityType.Documents:
                    case EntityType.Lists:
                        canUpdate = true;
                        break;
                    case EntityType.Discussions:            // need to override --> Project Manager can ONLY Update own Discussions
                        canUpdate = CanTeamMemberUpdateDiscussion ( currentUser, permissionsObject.AuthorId );
                        break;
                }
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.ProjectMember ) )
            {
                switch ( entityType )
                {
                    case EntityType.Setup:
                    case EntityType.Project:
                    case EntityType.Activity:
                        canUpdate = false;
                        break;
                    case EntityType.User:
                    case EntityType.Teams:                   // set to false or override here as permission is global and users can only edit themselves
                        canUpdate = CanUserUpdateThemselves ( currentUser.Id, currentUser.Login, permissionsObject.UserId );
                        break;
                    case EntityType.Documents:
                    case EntityType.Lists:
                        canUpdate = true;
                        break;
                    case EntityType.Work:                   // need to override in order to check if work is from project plan --> User CANNOT Edit plan item
                        canUpdate = CanTeamMemberUpdateWork ( permissionsObject );
                        break;
                    case EntityType.Discussions:            // need to override --> Team Member can ONLY Update own Discussions
                        canUpdate = CanTeamMemberUpdateDiscussion ( currentUser, permissionsObject.AuthorId );
                        break;
                }
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.PortalMember ) )
            {
                if ( entityType == EntityType.User )
                    // users can only edit themselves
                    canUpdate = CanUserUpdateThemselves ( currentUser.Id, currentUser.Login, permissionsObject.UserId );
                else
                    canUpdate = false;
            }
            else
                canUpdate = false;

            return canUpdate;
        }

        internal static bool CanUserDeleteItem ( IPermissions permissionsObject, User currentUser, EntityType entityType, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canDelete = false;
            using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                canDelete = CanUserDeleteItem ( permissionsObject, currentUser, entityType, web );
            }
            return canDelete;
        }

        private static bool CanUserDeleteItem ( IPermissions permissionsObject, User currentUser, EntityType entityType, SPWeb web )
        {
            bool canDelete = false;

            if ( currentUser.Groups.Contains ( KiiroGroup.PortalOwner ) )
            {
                if ( entityType == EntityType.Activity )
                    canDelete = false;
                else if ( entityType == EntityType.User || entityType == EntityType.Setup )
                    canDelete = !currentUser.ManageProjectsOnly;
                else
                    canDelete = true;
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.ProjectOwner ) )
            {
                switch ( entityType )
                {
                    case EntityType.Setup:
                    case EntityType.User:
                    case EntityType.Activity:
                        canDelete = false;
                        break;
                    case EntityType.Project:
                    case EntityType.Teams:
                    case EntityType.Work:
                    case EntityType.Documents:
                    case EntityType.Lists:
                    case EntityType.Discussions:
                        canDelete = true;
                        break;
                }
            }
            else if ( currentUser.Groups.Contains ( KiiroGroup.ProjectMember ) )
            {
                switch ( entityType )
                {
                    case EntityType.Setup:
                    case EntityType.User:
                    case EntityType.Project:
                    case EntityType.Activity:
                    case EntityType.Teams:
                        canDelete = false;
                        break;
                    case EntityType.Documents:
                    case EntityType.Lists:
                        canDelete = true;
                        break;
                    case EntityType.Work:                   // need to override in order to check if work is from project plan --> User CANNOT Delete plan item
                        canDelete = CanTeamMemberUpdateWork ( permissionsObject );
                        break;
                    case EntityType.Discussions:            // need to override --> Team Member can ONLY Delete own Discussions
                        canDelete = CanTeamMemberUpdateDiscussion ( currentUser, permissionsObject.AuthorId );
                        break;
                }
            }
            else
                canDelete = false;

            return canDelete;
        }

        public static bool CanUserUpdateThemselves ( User currentUser, User user, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canUpdate = false;
            using ( SPWeb web = SPHelpers.GetWeb ( user.SiteCollectionId, user.ServerRelativeUrl ) )
            {
                if ( currentUser.Groups.Contains ( KiiroGroup.PortalMember ) )
                {
                    canUpdate = CanUserUpdateThemselves ( currentUser.Id, currentUser.Login, user.Id );
                }
            }

            return canUpdate;
        }

        public static bool CanTeamMemberUpdateThemselves ( User currentUser, TeamMember teamMember, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canUpdate = false;
            using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                if ( !currentUser.Groups.Contains ( KiiroGroup.PortalOwner ) && !currentUser.Groups.Contains ( KiiroGroup.ProjectOwner ) )
                {
                    if ( !currentUser.Groups.Contains ( KiiroGroup.ProjectMember ) )
                        canUpdate = false;
                    else
                        canUpdate = CanUserUpdateThemselves ( currentUser.Id, currentUser.Login, teamMember.User.Id );
                }
                else
                    canUpdate = true;
            }
            return canUpdate;
        }

        public static bool CanUserUpdateThemselves ( int currentUserId, string currentUserLogin, int userIdToEdit )
        {
            return currentUserId == userIdToEdit && currentUserLogin.Trim ( ).ToLower ( ) != SecurityConstants.AD_AUTH_USERS_DOMAIN_GROUP_NAME.ToLower ( );
        }

        public static bool CanTeamMemberUpdateWork ( User currentUser, Work work, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canUpdate = false;
            using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                if ( currentUser.Groups.Contains ( KiiroGroup.PortalOwner ) || currentUser.Groups.Contains ( KiiroGroup.ProjectMember ) )
                {
                    canUpdate = CanTeamMemberUpdateWork ( work );
                }
            }
            return canUpdate;
        }

        private static bool CanTeamMemberUpdateWork ( IPermissions permissionsObject )
        {
            return permissionsObject is Work &&
                ( ( permissionsObject as Work ).PlanId != default ( int ) || ( permissionsObject as Work ).PlanId <= 0 );
        }

        public static bool CanTeamMemberUpdateDiscussion ( User currentUser, BaseEntity entity, Guid siteCollectionId, string serverRelativeUrl )
        {
            bool canUpdate = false;

            using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
            {
                if ( !currentUser.Groups.Contains ( KiiroGroup.ProjectOwner ) &&
                    !currentUser.Groups.Contains ( KiiroGroup.ProjectMember ) )
                {
                    canUpdate = false;
                }
                else
                {
                    canUpdate = CanTeamMemberUpdateDiscussion ( currentUser, entity.CreatedBy.Id );
                }
            }

            return canUpdate;
        }

        private static bool CanTeamMemberUpdateDiscussion ( User currentUser, int authorId )
        {
            return currentUser.Id == authorId;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Model/PermissionsModel.cs $
 * 
 * 41    2/08/10 5:04p Camerons
 * 
 * 40    1/25/10 1:17p Camerons
 * 
 * 39    1/12/10 12:03p Camerons
 * 
 * 38    26/11/09 10:35a Camerons
 * 
 * 37    17/11/09 6:46p Camerons
 * 
 * 36    7/11/09 2:41p Camerons
 * 
 * 35    26/10/09 1:53p Camerons
 * Fogbugz case #335 - Update logic in CanUserCreateItem for Portal Owners
 * 
 * 34    26/10/09 12:32p Camerons
 * Updated project delete permission bit for Project Owners group
 * 
 * 33    15/10/09 1:43p Camerons
 * 
 * 32    15/10/09 1:04p Camerons
 * 
 * 31    15/10/09 9:34a Camerons
 * 
 * 30    7/10/09 5:48p Camerons
 * 
 * 29    7/10/09 5:46p Camerons
 * Update for CanUserCreateItem - when user is portal owner, check
 * Licensing model for Projects and Users
 * 
 * 28    7/10/09 5:14p Camerons
 * Case #281, #285: Update SPDataHelpers.MakeUser to take SiteCollectionId
 * and ServerRelativeUrl as params. Used to properly determine the group
 * memberships.
 * 
 * 27    7/10/09 2:38p Camerons
 * Case #283: When deleting user, clear the User.ProjectIds and remove the
 * SPUser from any Kiiro SPGroups
 * 
 * 26    7/10/09 11:46a Camerons
 * Added PortalWebHasUniquePermissions method
 * 
 * 25    5/10/09 12:12p Stefanf
 * 
 * 24    30/09/09 1:08p Camerons
 * Implementing UserModel.GetOrCreateUser(). 
 * 
 * 23    29/09/09 3:52p Camerons
 * Changes involving AllUsers.aspx and SPGroups. AllUsers page now
 * displays the recoreds from the SPGroups instead of Kiiro user list.
 * Allows for security to be managed for the SharePoint admin screens. 
 * 
 * 22    29/09/09 2:19p Camerons
 * Implementing User.SPUserId
 * 
 * 21    23/09/09 4:46p Camerons
 * Fixed some old code dealing with User.ManageProjects
 * 
 * 20    22/09/09 6:03p Camerons
 * Code changes to support creating user on demand - version 1.1.x.x
 * 
 * 19    21/09/09 3:30p Camerons
 * First batch of changes for 1.1.x.x - Security groups update
 * 
 * 18    10/09/09 7:15p Camerons
 * 
 * 17    4/09/09 10:24a Camerons
 * 
 * 16    1/09/09 3:09p Camerons
 * 
 * 15    22/08/09 1:23p Shafia
 * 
 * 14    17/08/09 10:24a Camerons
 * Shafi:
 *  Thursday Aug13th, 2009:
 *  Changes:
 *   changed the SetUsersGroupPermissions to use
 *    admins.Users.GetByID(SPContext.Current.Web.CurrentUser.ID);
 *    when checking for user because the line
 * "admins.ContainsCurrentUser;" was not catching
 *    the current user info when creating subsite kiiro of a SharePoint
 * default site collection
 * 
 ************************************************************************/